package com.cfweb.api;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;

import com.cfweb.controller.LoginHandler;
import com.cfweb.exception.CloudFoundryApiException;
import com.cfweb.util.CloudFoundryClientUtil;
import com.cfweb.util.JsonUtil;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author (yufangjiang) Dec 2, 2014
 */
public class ServiceApi {
	/**
	 * 
	 * @param session
	 * @param sbId
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> listServiceBroker(HttpSession session, String sbId) throws Exception {
		List<Map<String, Object>> res = new ArrayList<Map<String, Object>>();
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/services?q=service_broker_guid%3A" + sbId;

		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> lr = (List<Map<String, Object>>) data.get("resources");
		String nextUrl = (String) data.get("next_url");
		while (nextUrl != null) {
			nextUrl = ApiCommonUtil.retriveAllPageResource(lr, nextUrl, session);
		}
		for (Map<String, Object> r : lr) {
			Map<String, Object> tmp = new HashMap<String, Object>();
			Map<String, Object> metadata = (Map<String, Object>) r.get("metadata");
			Map<String, Object> entity = (Map<String, Object>) r.get("entity");
			String guid = (String) metadata.get("guid");
			String label = (String) entity.get("label");
			tmp.put("label", label);
			tmp.put("guid", guid);
			List<Map<String, Object>> lt = listService(session, guid);
			tmp.put("plans", lt);
			res.add(tmp);
		}

		return res;
	}

	/**
	 * 列出所有可見servicePlan
	 * 
	 * @param session
	 * @param sId
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> listService(HttpSession session, String sId) throws Exception {
		List<Map<String, Object>> res = new ArrayList<Map<String, Object>>();
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/services/" + sId + "/service_plans";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> lr = (List<Map<String, Object>>) data.get("resources");
		String nextUrl = (String) data.get("next_url");
		while (nextUrl != null) {
			nextUrl = ApiCommonUtil.retriveAllPageResource(lr, nextUrl, session);
		}
		for (Map<String, Object> r : lr) {
			Map<String, Object> tmp = new HashMap<String, Object>();
			Map<String, Object> metadata = (Map<String, Object>) r.get("metadata");
			Map<String, Object> entity = (Map<String, Object>) r.get("entity");
			String guid = (String) metadata.get("guid");
			String name = (String) entity.get("name");
			boolean pub = (boolean) entity.get("public");
			tmp.put("name", name);
			tmp.put("guid", guid);
			tmp.put("public", pub);
			res.add(tmp);
		}
		return res;
	}

	/**
	 * 创建服务实例
	 * 
	 * @param session
	 * @param service
	 * @param planId
	 * @param name
	 * @param visibility
	 * @return
	 * @throws Exception
	 */
	public static boolean createServiceInstance(HttpSession session, String service, String planId, String name,
			boolean visibility) throws Exception {
		String orgName = (String) session.getAttribute(LoginHandler.ORG);
		String spaceName = (String) session.getAttribute(LoginHandler.SPACE);
		String spaceId = UserApi.get_space_id(session, orgName, spaceName);
		if (StringUtil.isEmpty(spaceId)) {
			return false;
		}

		if (!visibility) {
			if (!setPlanVisibility(session, planId, true)) {
				return false;
			}
		}
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_instances";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", name);
		params.put("service_plan_guid", planId);
		params.put("space_guid", spaceId);
		params.put("async", true);
		CloudFoundryClientUtil.doCCPost(urlPath, params, session);
		return true;
	}

	/**
	 * 把service plan设为可见
	 * 
	 * @param session
	 * @param planId
	 * @param visibility
	 * @return
	 * @throws Exception
	 */
	public static boolean setPlanVisibility(HttpSession session, String planId, boolean visibility) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_plans/" + planId;
		params.put("public", visibility);
		CloudFoundryClientUtil.doCCPut(urlPath, params, session);
		return true;
	}

	/**
	 * 获取具体的serverplan的guid
	 * 
	 * @param session
	 * @param sName
	 * @param spName
	 * @param spaceId
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String getGervicePlanGuid(HttpSession session, String sName, String spName, String spaceId)
			throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/spaces/" + spaceId + "/services?q=label%3A" + sName + "&inline-relations-depth=1";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> lr = (List<Map<String, Object>>) data.get("resources");
		for (Map<String, Object> r : lr) {
			Map<String, Object> metadata = (Map<String, Object>) r.get("metadata");
			Map<String, Object> entity = (Map<String, Object>) r.get("entity");
			String guid = (String) metadata.get("guid");
			String name = (String) entity.get("label");
			if (name.equals(sName)) {
				List<Map<String, Object>> lp = listService(session, guid);
				for (Map<String, Object> p : lp) {
					if (((String) p.get("name")).equals(spName)) {
						return (String) p.get("guid");
					}
				}
			}
		}
		return null;
	}

	/**
	 * 获取servicebroker guid
	 * 
	 * @param session
	 * @param sbName
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String getServiceBrokerGuid(HttpSession session, String sbName) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_brokers";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> lr = (List<Map<String, Object>>) data.get("resources");
		for (Map<String, Object> r : lr) {
			Map<String, Object> metadata = (Map<String, Object>) r.get("metadata");
			Map<String, Object> entity = (Map<String, Object>) r.get("entity");
			String guid = (String) metadata.get("guid");
			String name = (String) entity.get("name");
			if (name.equals(sbName)) {
				return guid;
			}
		}
		return null;
	}

	/**
	 * 获取服务实例不包括user-provided类型
	 * 
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getServices(HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_instances";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> response = (List<Map<String, Object>>) data.get("resources");
		String nextUrl = (String) data.get("next_url");
		while (nextUrl != null) {
			nextUrl = ApiCommonUtil.retriveAllPageResource(response, nextUrl, session);
		}
		return response;
	}

	@SuppressWarnings("unchecked")
	public static String getParticularServiceUUID(String serviceName, HttpSession session) throws Exception {
		String host = ((URL)session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_instances";
		if (serviceName != null) {
			urlPath = urlPath + "?q=name%3A" + serviceName;
		}
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> resources = (List<Map<String, Object>>) data.get("resources");
		if (resources.size() > 0) {
			return (String) ((Map<String, Object>) ((Map<String, Object>) resources.get(0)).get("metadata"))
					.get("guid");
		} else {
			// 获取user-provided-service-instance
			List<Map<String, Object>> userServices = getAllUserProvidedService(session);
			for (Map<String, Object> resouce : userServices) {
				Map<String, Object> entity = (Map<String, Object>) resouce.get("entity");
				if (serviceName.equals(entity.get("name"))) {
					return (String) ((Map<String, Object>) resouce.get("metadata")).get("guid");
				}
			}
			return null;
		}
	}

	public static String getParticularService(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + " /v2/service_instances/" + uuid;
		return CloudFoundryClientUtil.doCCGet(urlPath, null, session);
	}

	public static int getServiceSize(String org, String space, HttpSession session) throws Exception {
		List<Map<String, Object>> services = getServices(org, space, session);
		if (CollectionUtils.isEmpty(services)) {
			return 0;
		}
		return services.size();
	}

	public static List<Map<String, Object>> getServices(String org, String space, HttpSession session) throws Exception {
		String spaceId = UserApi.get_space_id(session, org, space);
		if (StringUtil.isEmpty(spaceId)) {
			throw new CloudFoundryApiException(500, "can't find space");
		}
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/spaces/" + spaceId + "/summary";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		@SuppressWarnings("unchecked")
		List<Map<String, Object>> response = (List<Map<String, Object>>) data.get("services");
		return response;
	}

	public static void deleteServiceInstance(String serviceName, HttpSession session) throws Exception {
		String guid = getParticularServiceUUID(serviceName, session);
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/service_instances/" + guid;
		CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
	}

	/**
	 * 获取user-provided服务
	 * 
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getAllUserProvidedService(HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/user_provided_service_instances";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> response = (List<Map<String, Object>>) data.get("resources");
		String nextUrl = (String) data.get("next_url");
		while (nextUrl != null) {
			nextUrl = ApiCommonUtil.retriveAllPageResource(response, nextUrl, session);
		}
		return response;
	}
}
